use axum::http::HeaderMap;
use tower_cookies::{Cookie,Cookies};

use crate::models::User;

// pub const COOKIE_NAME: &str = "session_id";	//设置cookie name
pub const USER_ID_NAME: &str = "user_id" ;

/*

    给每个用户一个user_id，然后以每个用户的user_id作为键，session_id的值作为值，就可以判断一个用户是否已经登录。
*/



/// 将 user ID 保存到 Cookie
pub fn save_user_id_to_cookie(user_id: String, cookies:Cookies) {
    cookies.add(Cookie::new(USER_ID_NAME, user_id.to_string()));
}


/// 从 cookie 中获取user id
pub fn get_user_id_from_cookie(cookies:Cookies) -> Option<String> {
    let cookie = cookies.get(USER_ID_NAME);
    if cookie.is_none(){
        return None;
    }
    let user_id = cookie.unwrap().value().to_string();

    Some(user_id)
}

pub fn get_user_id_from_header(headers: &HeaderMap) -> Option<String> {
    let cookie = headers
        .get(axum::http::header::COOKIE)
        .and_then(|value| value.to_str().ok())
        .map(|value| value.to_string());
    match cookie {
        Some(cookie) => {
            let cookie = cookie.as_str();
            let cs: Vec<&str> = cookie.split(';').collect();
            for item in cs {
                let item: Vec<&str> = item.split('=').collect();
                if item.len() != 2 {
                    continue;
                }
                let key = item[0];
                let val = item[1];
                let key = key.trim();
                let val = val.trim();
                if key == USER_ID_NAME {
                    return Some(val.to_string());
                }
            }
            None
        }
        None => None,
    }
}
pub fn set_cookie(value: &str) -> HeaderMap {
    let c = format!("{}={}", USER_ID_NAME, value);
    let mut hm = HeaderMap::new();
    hm.insert(axum::http::header::SET_COOKIE, (&c).parse().unwrap());
    hm
}

pub async fn get_user_from_cookies(cookies:Cookies) -> Result<User,String> {
    let user_id = get_user_id_from_cookie(cookies).unwrap();

    let user_id: i32 = user_id.parse().unwrap();

    let user = User::fetch_one_by_id(user_id).await.map_err(|err| err.to_string())?;
    Ok(user)

}